//
//  ViewController.m
//  webDemo
//
//  Created by 何涛 on 2017/6/27.
//  Copyright © 2017年 thomasho. All rights reserved.
//

#import "WebVC.h"
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>

//WKWebview
#import <WebKit/WebKit.h>
#import "WeakScriptMessageDelegate.h"

//for tips
#define action(msg) [UIAlertAction actionWithTitle:msg style:UIAlertActionStyleDefault handler:nil]
#define actionWithBlock(msg,block) [UIAlertAction actionWithTitle:msg style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){block?block():nil;}]
#define showMessageAndActioins(msg,actions) UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"提示",nil) message:msg preferredStyle:UIAlertControllerStyleAlert];\
                         if([actions count]) for(id action in actions) [alert addAction:action];\
                         else [alert addAction:action(NSLocalizedString(@"好的",nil))];\
                         [self presentViewController:alert animated:YES completion:nil];

#define showMessage(msg) showMessageAndActioins(msg,@[]);

@interface WebVC ()<CLLocationManagerDelegate,CBCentralManagerDelegate,WKScriptMessageHandler,WKNavigationDelegate,WKUIDelegate>

//WKWebView
@property (nonatomic,strong) NSString *webUrl;
@property (nonatomic,strong) WKWebView *wkwebView;

//scan iBeacon & ble check
@property (nonatomic,strong) CLLocationManager *locationManager;
@property (nonatomic,strong) CBCentralManager *centralManager;

//share json data
@property (nonatomic,strong) NSString * shareJson;

@end

@implementation WebVC

- (instancetype)initWithUrl:(NSString *)url {
    self = [super init];
    if (self) {
        self.webUrl = url;
    }
    return self;
}
- (void) refresh:(NSString *)url {
    self.webUrl = url;
    [self loadWKWebview];
}
#pragma mark - **************** 页面开始加载webView及动画
- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIActivityIndicatorView *AIV = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [AIV startAnimating];
    self.navigationItem.titleView = AIV;
    self.view.backgroundColor  = [UIColor whiteColor];
    
    //不允许自动调整，第一子视图Insets
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    //屏幕常亮
    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
    
    //IOS 8才能使用WKWebView
    [self loadWKWebview];
    [self performSelector:@selector(timeOut) withObject:nil afterDelay:15];
}

//超时处理
- (void)timeOut {
    if ([self.navigationItem.titleView isKindOfClass:[UIActivityIndicatorView class]]) {
        NSArray *actions = @[action(NSLocalizedString(@"取消", nil)),actionWithBlock(NSLocalizedString(@"立即刷新", nil),^(){ [self loadWKWebview];})];
        showMessageAndActioins(NSLocalizedString(@"加载超时，请重试", nil),actions);
    }
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(timeOut) object:nil];
}

//每次页面进入，检测蓝牙+定位状态
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if ([CLLocationManager isRangingAvailable]  == NO) {
        NSLog(@"Device not support iBeacon");
    }else {
        //options控制不自动弹窗
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],CBCentralManagerOptionShowPowerAlertKey, nil];
        self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) options:options];
    }
}

//检测是否dealloc
- (void)dealloc {
    NSLog(@"check if dealloc");
    [self.wkwebView.configuration.userContentController removeScriptMessageHandlerForName:@"share"];
    [self.wkwebView.configuration.userContentController removeScriptMessageHandlerForName:@"detail"];
    [self.wkwebView.configuration.userContentController removeScriptMessageHandlerForName:@"bleEnable"];
}

#pragma mark - **************** 蓝牙、定位相关
//蓝牙状态回调，检测定位权限，尝试调用定位初始化
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    if (central.state == CBPeripheralManagerStatePoweredOn) {
        [self performSelectorOnMainThread:@selector(initLocation) withObject:nil waitUntilDone:NO];
    }else{
        showMessage(NSLocalizedString(@"需要打开蓝牙",nil));
    }
}

//定位初始化，IOS8定位权限请求，方向请求，开始扫描Region下的定位设备（权限通过之后会开始回调）
- (void)initLocation {
    self.locationManager = [[CLLocationManager alloc] init];
    [self.locationManager requestAlwaysAuthorization];
    self.locationManager.delegate = self;
    //限制扫描设备UUID
    CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:@"FDA50693-A4E2-4FB1-AFCF-C6EB07647825"] identifier:@"region"];
    [self.locationManager startRangingBeaconsInRegion:region];
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    if (status < 3) {
        NSLog(@"定位权限不够");
    }else{
        NSLog(@"定位权限正常");
    }
}
//扫描设备回调
- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region{
    if (self.wkwebView.isLoading) {
        //等待web加载完成
        return;
    }
    //筛选信号[0,-78]之间设备
    NSMutableArray *scanBeacons = [NSMutableArray array];
    for (CLBeacon *pb in beacons) {
        if (pb.accuracy < 0 || pb.rssi <= -78) {
            continue;
        }
        NSDictionary *dic = @{@"uuid":pb.proximityUUID.UUIDString,
                              @"major":pb.major,
                              @"minor":pb.minor,
                              @"accuracy":[NSString stringWithFormat:@"%.2f",pb.accuracy],
                              @"rssi":@(pb.rssi),
                              @"proximity":@(pb.proximity)};
        [scanBeacons addObject:dic];
    }
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:@{@"beacons":scanBeacons} options:0 error:nil];
    NSString *json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    [self.wkwebView evaluateJavaScript:[NSString stringWithFormat:@"setTimeout(on_brtbeacon_beacon_search(%@),0);",json] completionHandler:nil];
}

#pragma mark - 回馈js蓝牙定位检测状态
- (void)bleEnable {
    //0 正常  1 定位权限问题 2 蓝牙未开
    NSString *msg = @"0";
    if ([CLLocationManager authorizationStatus] <= kCLAuthorizationStatusDenied) msg = @"1";
    if (self.centralManager.state != CBCentralManagerStatePoweredOn) msg = @"2";
    NSString *js =[NSString stringWithFormat:@"setTimeout(on_app_ble_enable_callback(%@),0);",msg];
    [self.wkwebView evaluateJavaScript:js completionHandler:nil];
}

#pragma mark - **************** 分享部分
//显示选择分享平台
- (void)showShareView:(id)dic {
    if ([dic isKindOfClass:[NSString class]]) {
        dic =[NSJSONSerialization JSONObjectWithData:[dic dataUsingEncoding:NSUTF8StringEncoding] options:0 error:NULL];
    }
    UIImage *imageToShare = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:dic[@"imgUrl"]]]];
    NSString *textToShare = dic[@"title"];
    NSString *descriptionToShare = dic[@"desc"];//description = dic[@"desc"];
    NSURL *urlToShare = [NSURL URLWithString:dic[@"link"]];
    NSMutableArray *activityItems = [NSMutableArray array];
    if (imageToShare) {
        [activityItems addObject:imageToShare];
    }
    if (textToShare.length) {
        [activityItems addObject:textToShare];
    }
    if (descriptionToShare.length) {
        [activityItems addObject:descriptionToShare];
    }
    if (urlToShare) {
        [activityItems addObject:urlToShare];
    }
    
    UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:nil];
    if (activityVC.popoverPresentationController) {
        activityVC.popoverPresentationController.sourceView = self.wkwebView;
        activityVC.popoverPresentationController.sourceRect = CGRectMake(self.wkwebView.center.x, self.wkwebView.frame.size.height, 1,1);
        activityVC.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
    }
    [self presentViewController:activityVC animated:YES completion:nil];
    activityVC.completionWithItemsHandler = ^(UIActivityType  _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
        if (completed) {
            NSLog(@"completed");
            //分享 成功
        } else  {
            NSLog(@"cancled");
            //分享 取消
        }
    };
}

#pragma mark - **************** 加载wkWebView

//初始化并注入WKWeb本地分享对象
- (void)loadWKWebview {
    if (self.wkwebView == nil) {
        //添加本地响应方法（WeakScriptMessageDelegate弱引用）
        WKUserContentController *userContentController = [[WKUserContentController alloc] init];
        WeakScriptMessageDelegate *weakDelegaete = [[WeakScriptMessageDelegate alloc] initWithDelegate:self];
        [userContentController addScriptMessageHandler:weakDelegaete name:@"share"];
        [userContentController addScriptMessageHandler:weakDelegaete name:@"detail"];
        [userContentController addScriptMessageHandler:weakDelegaete name:@"bleEnable"];
        
        //为js方法添加WKWebView支持：注入h5分享share和bleEnable接口的js代码，如果使用UIWebView请使用JSContext注入。
        //IOS8+:window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
        NSString *js = @"var zs = {\
                            'share': function(info) {\
                                        window.webkit.messageHandlers.share.postMessage(info);\
                                    },\
                            'detail': function(info) {\
                                        window.webkit.messageHandlers.detail.postMessage(info);\
                            },\
                            'bleEnable': function() {\
                                        window.webkit.messageHandlers.bleEnable.postMessage(null);\
                                    }\
                        };";
        WKUserScript *script = [[WKUserScript alloc] initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
        [config setUserContentController:userContentController];
        [config.userContentController addUserScript:script];
        
        //添加WKWebView
        CGRect frame = self.view.bounds;
        frame.size.height -=64;
        frame.origin.y = 64;
        self.wkwebView = [[WKWebView alloc] initWithFrame:frame configuration:config];
        self.wkwebView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        [self.view insertSubview:self.wkwebView atIndex:0];
        self.wkwebView.navigationDelegate = self;
        self.wkwebView.UIDelegate = self;
    }
    //开始页面请求
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:_webUrl]];
    [self.wkwebView loadRequest:request];
}

#pragma mark - **************** wkWebView回调
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    self.navigationItem.titleView = nil;
    self.title = webView.title;
}
//页面白屏重新加载
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
    [webView reload];
}

//JS调用Navtive触发回调
//window.webkit.messageHandlers.share.postMessage(null);
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if([message.name isEqualToString:@"share"]){
        [self showShareView:message.body];
    }
    if ([message.name isEqualToString:@"bleEnable"]) {
        [self bleEnable];
    }
    if ([message.name isEqualToString:@"detail"]) {
        //to do
        showMessage(@"detail clicked.");
    }
}
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"提示",nil) message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:NSLocalizedString(@"确认",nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
    
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    //    DLOG(@"msg = %@ frmae = %@",message,frame);
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"提示",nil) message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:NSLocalizedString(@"取消",nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [alertController addAction:([UIAlertAction actionWithTitle:NSLocalizedString(@"确认",nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.text = defaultText;
    }];
    [alertController addAction:([UIAlertAction actionWithTitle:NSLocalizedString(@"完成",nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields[0].text?:@"");
    }])];
    
    [self presentViewController:alertController animated:YES completion:nil];
}

@end
